# -*- coding:utf-8 -*-

import sys
import time
from pynput.keyboard import Key, Listener
from PySide2.QtCore import *
from PySide2.QtWidgets import *


class STATUS:
    STOP = 0
    RUNNING = 1
    PAUSE = 2


class Key2Frame(QWidget):
    startClicked = Signal(dict)
    pauseClicked = Signal(dict)
    stopClicked = Signal(dict)

    def __init__(self,title=None,parent=None):
        super(Key2Frame, self).__init__(parent)

        self.status = STATUS.STOP  # 0:停止 1:开始  2:暂停
        self.gray = "QLabel{background-color: #bababa}"
        self.green = "QLabel{background-color: #bbf236}"
        self.show_style = "QLabel{color:#7cdb29}" \
                          "QLabel{font-size:85px}"
        self.start_time = time.time()
        # self.listener = None  # 监听器
        self.listener = None
        self.age = 0  # 年龄，当开始记录时，保持增长，当按下暂停与停止键时，记录当前最后一个key up时的时间，每次继续后，
        # 更新开始时间前，该值减去原记录的开始时间的差值，更新此时为开始时间，新开始时间+上该差值 就是新的age
        self.key_frame = {}  # {key:{'start':[],'end:':[]},key2:{},..}
        self.btn_on_style = """QPushButton{color:#8be133}
                                  QPushButton:hover{color:red}
                                  QPushButton{background-color:#A9A9A9}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:5px 1px}"""

        self.btn_off_style = """QPushButton{color: #6b6b6b}
                                  QPushButton:hover{color:red}
                                  QPushButton{background-color:#A9A9A9}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:5px 1px}"""

        self.btn_pause_style = """QPushButton{color: #FF7F24}
                                  QPushButton:hover{color:red}
                                  QPushButton{background-color:#A9A9A9}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:5px 1px}"""
        ##FF7F24


        self.resize(600, 600)
        self.setWindowTitle('按键生成帧' if not title else title)
        self.main_layout = QVBoxLayout()

        self.btn_layout = QHBoxLayout()
        self.btn_layout.setSpacing(30)
        self.start_btn = QPushButton('开始')
        self.start_btn.clicked.connect(self._on)
        self.pause_btn = QPushButton('暂停')
        self.pause_btn.clicked.connect(self._pause)
        self.stop_btn = QPushButton('停止')
        self.stop_btn.clicked.connect(self._off)
        self.btn_layout.addWidget(self.start_btn)
        self.btn_layout.addWidget(self.pause_btn)
        self.btn_layout.addWidget(self.stop_btn)

        self._off()

        self.mid_layout = QHBoxLayout()
        self.mid_show = QLabel('')
        self.mid_show.setAlignment(Qt.AlignCenter)
        self.mid_show.setFixedSize(450, 450)
        self.mid_show.setStyleSheet(self.show_style)
        self.mid_layout.addWidget(self.mid_show)

        self.show_layout = QHBoxLayout()
        self.key_label = QLabel('状态:')
        self.key_label.setFixedWidth(80)
        self.color_label = QLabel('')
        self.color_label.setFixedSize(80, 20)
        self.color_label.setStyleSheet(self.gray)

        self.show_layout.addWidget(self.key_label)
        self.show_layout.addWidget(self.color_label)

        self.main_layout.addLayout(self.btn_layout)
        self.main_layout.addLayout(self.mid_layout)
        self.main_layout.addLayout(self.show_layout)

        self.setLayout(self.main_layout)
        self.defocuse()


    def on_press(self, key):
        # 监听按键
        if self.status == STATUS.RUNNING:
            skey = str(key).replace("'", "").replace('Key.','')
            self.mid_show.setText(skey)
            self.color_label.setStyleSheet(self.green)
            QApplication.processEvents()
            var = getattr(self, skey, False)  # 获取当前按键变量
            delta_time = time.time() - self.start_time
            if not var:  # 当不存在该按键变量或按键不被按下时,再添加变量 记录时间，否则不记录时间
                setattr(self, skey, True)
                if skey not in self.key_frame.keys():
                    self.key_frame[skey] = {'start': [], 'end': []}
                down_time = self.age + delta_time
                self.key_frame[skey]['start'].append(down_time)

    def on_release(self, key):
        # 监听释放
        if self.status == STATUS.RUNNING:
            skey = str(key).replace("'", "").replace('Key.','')
            self.mid_show.setText('')
            self.color_label.setStyleSheet(self.gray)
            QApplication.processEvents()
            setattr(self, skey, False)
            delta_time = time.time() - self.start_time
            up_time = self.age + delta_time
            self.key_frame[skey]['end'].append(up_time)
            if key == Key.esc:
                self._off()


    def saveMS(self, end_time):
        """
        保存按键时间点。
        :param: end_time 最后停止时间，当还正在down状态的key没有up归为时，弥补这个end值
        :return:
        """
        for k, v in self.key_frame.items():
            start = v['start']
            end = v['end']
            if len(end) < len(start):
                end.append(end_time)

        # with open('key.map', 'w', encoding='utf8') as w:
        #     w.write(str(self.key_frame))

    def defocuse(self):
        for i in self.children():
            if isinstance(i, QVBoxLayout) or isinstance(i, QHBoxLayout):
                pass
            else:
                i.setFocusPolicy(Qt.NoFocus)

    def _on(self):
        self.start_btn.setStyleSheet(self.btn_on_style)
        self.pause_btn.setStyleSheet(self.btn_off_style)
        self.stop_btn.setStyleSheet(self.btn_off_style)

        if self.status == STATUS.PAUSE:
            self.start_time = time.time()  # + self.age

        elif self.status == STATUS.RUNNING:
            pass
        else:
            self.key_frame.clear()
            self.start_time = time.time()
            self.listener = Listener(on_press=self.on_press, on_release=self.on_release)
            self.listener.start()
        self.status = STATUS.RUNNING
        self.startClicked.emit(self.key_frame)


    def _off(self):
        self.status = STATUS.STOP
        delta_time = time.time() - self.start_time
        stop_time = self.age + delta_time

        self.start_btn.setStyleSheet(self.btn_off_style)
        self.pause_btn.setStyleSheet(self.btn_off_style)
        self.stop_btn.setStyleSheet(self.btn_off_style)

        if self.listener:
            self.listener.stop()
            self.saveMS(stop_time)
        self.stopClicked.emit(self.key_frame)

    def _pause(self):
        if self.status == STATUS.RUNNING:
            self.status = self.status if self.status != STATUS.RUNNING else STATUS.PAUSE
            delta_time = time.time() - self.start_time
            self.age += delta_time
            self.start_time = time.time()
            self.start_btn.setStyleSheet(self.btn_off_style)
            self.pause_btn.setStyleSheet(self.btn_pause_style)
            self.stop_btn.setStyleSheet(self.btn_off_style)
        self.pauseClicked.emit(self.key_frame)